home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / QuickDraw™ GX / Programming Stuff / Sample Code / Graphics Samples / ShapePart Browser ƒ / ShapeAction.c < prev    next >
Encoding:
Text File  |  1995-04-10  |  8.4 KB  |  354 lines  |  [TEXT/KAHL]

  1. /*
  2.  *    ShapeAction.c
  3.  *
  4.  *    Robert Dierkes,  April 26, 1993
  5.  */
  6.  
  7.  
  8. #undef    MAC_HEADERS
  9.  
  10.  
  11. /*------------------*/
  12. /*    Include Files    */
  13. /*------------------*/
  14. #ifndef    MAC_HEADERS
  15.     #include <Dialogs.h>
  16.     #include <Controls.h>
  17. #endif    MAC_HEADERS
  18.  
  19. #define debugging                /* for gxGraphicNotices */
  20.  
  21. #include "graphics routines.h"
  22. #include "graphics libraries.h"
  23. #include "qd library.h"            /* ShortRectToFixed for DrawGrayBox */
  24.  
  25. #include "ResourceIDs.h"
  26. #include "ShapeAction.h"
  27. #include "ShapeSetup.h"
  28.  
  29.  
  30. /*----------------------*/
  31. /*    Global Declarations    */
  32. /*----------------------*/
  33.  
  34.  
  35. /*------------------------------*/
  36. /*    External Declarations     */
  37. /*------------------------------*/
  38. extern    GlobalStructure    globals;
  39.  
  40.  
  41. /*------------------------------*/
  42. /*       Local ProtoTypes       */
  43. /*------------------------------*/
  44. void ShowLocalBounds (gxShape *p1stShape, long shapeCount);
  45. void HighlightShapePartBoxes (ControlHandle *ph1stControl, gxShapePart partsHit);
  46. long GetShapeBoxIndexFromPoint (gxShape boxes, gxPoint *pWhere);
  47. void UpdateShapeName (gxShape theShape, gxShapeType *pLastType);
  48. pascal void DrawGrayBox (WindowPtr pWindow, short itemNum);
  49.  
  50.  
  51.     void
  52. ShowLocalBounds (gxShape *p1stShape, long shapeCount)
  53. {
  54.     register
  55.     gxShape        *pShape,
  56.                 rectShape;
  57.     gxRectangle    bounds;
  58.  
  59.     pShape = p1stShape + shapeCount - 1;
  60.  
  61.     rectShape = GXNewShape (gxRectangleType);
  62.     GXSetShapeFill (rectShape, gxClosedFrameFill);
  63.     SetShapeCommonColor (rectShape, gxGray);
  64.  
  65.     while (shapeCount--)
  66.     {
  67.         GXGetShapeLocalBounds (*pShape--, &bounds);
  68.         GXSetRectangle (rectShape, &bounds);
  69.         GXDrawShape (rectShape);
  70.     }
  71.  
  72.     GXDisposeShape (rectShape);
  73. }
  74.  
  75.  
  76.     void
  77. ShowControlPoints (gxShape *p1stShape, long shapeCount)
  78. {
  79.     register
  80.     gxShape        *pShape;
  81.     long        contourCount,
  82.                 pointCount;
  83.     gxPoint        pt;
  84.     gxShape        pointShape;
  85.     gxRectangle    bounds;
  86.  
  87.     pShape = p1stShape + shapeCount - 1;
  88.     pointShape = GXNewShape (gxRectangleType);
  89.  
  90.     while (shapeCount--)
  91.     {
  92.         /* gxGlyphType has too many control points so skip it */
  93.         if (GXGetShapeType (*pShape) != gxGlyphType)
  94.         {
  95.             contourCount = GXCountShapeContours (*pShape);
  96.             while (contourCount--)
  97.             {
  98.                 pointCount = GXGetShapePoints (*pShape, 1, gxSelectToEnd, nil);
  99.                 while (pointCount)
  100.                 {
  101. ///                    GetShapeIndexPoint (*pShape, pointCount--, &pt);
  102.                     GXGetShapePoints (*pShape, pointCount--, 1, &pt);
  103.                     bounds.left   = pt.x - fixed1;
  104.                     bounds.top    = pt.y - fixed1;
  105.                     bounds.right  = pt.x + fixed1;
  106.                     bounds.bottom = pt.y + fixed1;
  107.                     GXSetRectangle (pointShape, &bounds);
  108.                     GXDrawShape (pointShape);
  109.                 }
  110.             }
  111.         }
  112.         pShape--;
  113.     }
  114.  
  115.     GXDisposeShape (pointShape);
  116. }
  117.  
  118.  
  119. /*
  120.  *
  121.  */
  122.      void
  123. HighlightShapePartBoxes (ControlHandle *ph1stControl, gxShapePart partsHit)
  124. {
  125.     #define    controlCount    11
  126.  
  127.     ControlHandle    *pControl;
  128.     gxRectangle        controlRect;
  129.     gxShape            highlight;
  130.     static
  131.     gxShapePart        lastPartsHit = gxAnyPart;
  132.     gxShapePart        partMask;
  133.  
  134.     if (partsHit == lastPartsHit)
  135.         return;
  136.  
  137.     highlight = GXNewShape (gxRectangleType);
  138.     GXSetShapeFill (highlight, gxClosedFrameFill);
  139.     GXIgnoreGraphicsNotice (color_already_set);
  140.  
  141.     partMask = gxPatternPart;
  142.     for (pControl = ph1stControl + controlCount; --pControl >= ph1stControl; partMask >>= 1)
  143.     {
  144.         /* Compare single bit of current shapeParts against previous shapeParts */
  145.         if ((partsHit & partMask) != (lastPartsHit & partMask))
  146.         {
  147.             (void) ShortRectToFixed (&(**pControl)->contrlRect, &controlRect);
  148.             controlRect.left   -= fixed1;
  149.             controlRect.top    -= fixed1;
  150.             controlRect.right  += fixed1;
  151.  
  152.             GXSetRectangle (highlight, &controlRect);
  153.             SetShapeCommonColor (highlight, (partsHit & partMask) ? red : gxWhite);
  154.             GXDrawShape (highlight);
  155.         }
  156.     }
  157.     lastPartsHit = partsHit;
  158.  
  159.     GXPopGraphicsNotice ();
  160.     GXDisposeShape (highlight);
  161. }
  162.  
  163.  
  164.     pascal void
  165. DrawGrayBox (WindowPtr pWindow, short itemNum)
  166. {
  167.     GrafPtr        savedPort;
  168.     Rect        shortBounds;
  169.     gxRectangle    bounds;
  170.     gxShape        boxShape;
  171.     short        itemType;
  172.     Handle        itemHandle;
  173.  
  174.     GetPort (&savedPort);
  175.     SetPort (pWindow);
  176.  
  177.     GetDItem (pWindow, itemNum, &itemType, &itemHandle, &shortBounds);
  178.     ShortRectToFixed (&shortBounds, &bounds);
  179.     boxShape = GXNewRectangle (&bounds);
  180.     GXSetShapeFill (boxShape, gxClosedFrameFill);
  181.     GXSetShapePen (boxShape, 4 * fixed1);
  182.     SetShapeCommonColor (boxShape, grayish + silver);
  183.     GXDrawShape (boxShape);
  184.     GXDisposeShape (boxShape);
  185.  
  186.     SetPort (savedPort);
  187.  
  188. }
  189.  
  190.  
  191.     void
  192. UpdateHitTestWindow (WindowPtr pWindow)
  193. {
  194.     register
  195.     gxShape        *pShape;
  196.     long        shapeCount,
  197.                 shapeCountDown;
  198.  
  199.     UpdtDialog (pWindow, pWindow->visRgn);
  200.  
  201.     DrawGrayBox (pWindow, userGrayShapeNameBox);
  202.     DrawGrayBox (pWindow, userGrayShapePartsBox);
  203.     HighlightShapePartBoxes (&globals.hBounds, globals.partsHit);
  204.  
  205.     shapeCount = shapeCountDown = GXCountShapeContours (globals.boxes);
  206.  
  207.     /* Draw the background boxes */
  208.     GXDrawShape (globals.boxes);
  209.  
  210.     if (globals.showLocalBounds)
  211.         ShowLocalBounds (globals.pShapes, shapeCount);
  212.  
  213.     /* Draw all the hit testing shapes */
  214.     pShape = globals.pShapes;
  215.     while (shapeCountDown--)
  216.         GXDrawShape (*pShape++);
  217.  
  218.     if (globals.showControlPoints)
  219.         ShowControlPoints (globals.pShapes, shapeCount);
  220. }
  221.  
  222.  
  223.     long
  224. GetShapeBoxIndexFromPoint (gxShape boxes, gxPoint *pWhere)
  225. {
  226.     gxRectangle    bounds;
  227.     long        index;
  228.  
  229.     index = GXCountShapeContours (boxes);
  230.     while (index)
  231.     {
  232.         GXGetShapeBounds (boxes, index, &bounds);
  233.         if (GXTouchesRectanglePoint (&bounds, pWhere))
  234.             return (index - 1);
  235.         index--;
  236.     }
  237.     return (notOnAnyShape);
  238. }
  239.  
  240.  
  241.     void
  242. UpdateShapeName (gxShape theShape, gxShapeType *pLastType)
  243. {
  244.     gxShapeType    newType;
  245.     Handle        itemHandle;
  246.     Str255        shapeNames[] = {"\pPoint",
  247.                                 "\pLine",
  248.                                 "\pCurve",
  249.                                 "\pRectangle",
  250.                                 "\pPolygon",
  251.                                 "\pPath",
  252.                                 "\pBitmap",
  253.                                 "\pText",
  254.                                 "\pGlyph",
  255.                                 "\p"
  256.                                 };
  257.     StringPtr    pShapeName;
  258.     short        itemType;
  259.     Rect        itemRect;
  260.  
  261.     if (theShape == nil)
  262.         newType = gxEmptyType;
  263.     else if ((newType = GXGetShapeType (theShape)) == *pLastType)
  264.         return;
  265.  
  266.     *pLastType = newType;
  267.  
  268.     switch (newType)
  269.     {
  270.         case gxPointType:        pShapeName = shapeNames [0];    break;
  271.         case gxLineType:        pShapeName = shapeNames [1];    break;
  272.         case gxCurveType:        pShapeName = shapeNames [2];    break;
  273.         case gxRectangleType:    pShapeName = shapeNames [3];    break;
  274.         case gxPolygonType:        pShapeName = shapeNames [4];    break;
  275.         case gxPathType:        pShapeName = shapeNames [5];    break;
  276.         case gxBitmapType:        pShapeName = shapeNames [6];    break;
  277.         case gxTextType:        pShapeName = shapeNames [7];    break;
  278.         case gxGlyphType:        pShapeName = shapeNames [8];    break;
  279.         default:                pShapeName = shapeNames [9];    break;
  280.     }
  281.  
  282.     GetDItem (qd.thePort, staticShapeName, &itemType, &itemHandle, &itemRect);
  283.     SetIText (itemHandle, pShapeName);
  284. }
  285.  
  286.  
  287. /*
  288.     Draws a red rectangle around check box if the given point hit that type of gxShape part.
  289. */
  290.     void
  291. UpdateShapePartInfo (Point *pQDWhere, GlobalStructure *pG)
  292. {
  293.     gxPoint            where;
  294.     gxHitTestInfo    hitInfo;
  295.     long            boxIndex;
  296.     static
  297.     gxShapeType        lastType = gxEmptyType;
  298.     gxShape            shapeHit;
  299.  
  300.     ShortPointToFixed (pQDWhere, &where);
  301.     boxIndex = GetShapeBoxIndexFromPoint (pG->boxes, &where);
  302.  
  303.     /* Change checkbox titles if point is in glyph gxShape */
  304.     if (boxIndex == kWordGlyphs  &&  lastType != gxGlyphType)
  305.     {
  306.         Point    joinSize     = {16, 106},
  307.                 startCapSize = {16, 90},
  308.                 endCapSize     = {16, 88},
  309.                 dashSize     = {16, 100};
  310.  
  311.         SizeControl (pG->hJoin, joinSize.h, joinSize.v);
  312.         SizeControl (pG->hStartCap, startCapSize.h, startCapSize.v);
  313.         SizeControl (pG->hEndCap, endCapSize.h, endCapSize.v);
  314.         SizeControl (pG->hDash, dashSize.h, dashSize.v);
  315.         SetCTitle (pG->hJoin,      "\pGlyph Bounds");
  316.         SetCTitle (pG->hStartCap, "\pGlyph First");
  317.         SetCTitle (pG->hEndCap,   "\pGlyph Last");
  318.         SetCTitle (pG->hDash,      "\pSide Bearing");
  319.     }
  320.     else if (boxIndex != kWordGlyphs  &&  lastType == gxGlyphType)
  321.     {
  322.         Point    joinSize     = {16, 48},
  323.                 startCapSize = {16, 82},
  324.                 endCapSize     = {16, 72},
  325.                 dashSize     = {16, 52};
  326.         Rect    invalid         = {274, 528, 354, 588};
  327.  
  328.         InvalRect (&invalid);
  329.         SizeControl (pG->hJoin, joinSize.h, joinSize.v);
  330.         SizeControl (pG->hStartCap, startCapSize.h, startCapSize.v);
  331.         SizeControl (pG->hEndCap, endCapSize.h, endCapSize.v);
  332.         SizeControl (pG->hDash, dashSize.h, dashSize.v);
  333.         SetCTitle (pG->hJoin,      "\pJoin");
  334.         SetCTitle (pG->hStartCap, "\pStart Cap");
  335.         SetCTitle (pG->hEndCap,      "\pEnd Cap");
  336.         SetCTitle (pG->hDash,      "\pDash");
  337.     }
  338.  
  339.     if (boxIndex == notOnAnyShape)
  340.     {
  341.         shapeHit = nil;
  342.         hitInfo.what = gxNoPart;
  343.     }
  344.     else
  345.     {
  346.         shapeHit = pG->pShapes [boxIndex];
  347.         GXHitTestShape (pG->pShapes [boxIndex], &where, &hitInfo);
  348.     }
  349.  
  350.     UpdateShapeName (shapeHit, &lastType);
  351.     HighlightShapePartBoxes (&pG->hBounds, hitInfo.what);
  352.     pG->partsHit = hitInfo.what;
  353. }
  354.